package com.navinfo.platform.bigdata.hive.udf;

import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;

/**
 * 获取num第index位bit值的字符串
 */
@Description(name = "status",
        value = "_FUNC_(num, index) - returns the index bit value of num",
        extended = "Example:\n   " +
                "> SELECT _FUNC_(11, 0) FROM src;\n"+
                "> SELECT _FUNC_(\"11\", 0) FROM src;"
)
public class StatusUDF extends UDF {
    /**
     * 获取num第index位的bit值
     * @param num
     * @param index
     * @return
     */
    public Text evaluate(Text num, IntWritable index) {
        if (!checkData(num, index)) {
            return new Text("0");
        }
        return new Text(String.valueOf(getToBinary(Long.parseLong(num.toString()), index.get())));
    }
    /**
     * 获取num第index位的bit值
     * @param num
     * @param index
     * @return
     */
    public Text evaluate(LongWritable num, IntWritable index) {
        if (!checkData(num, index)) {
            return new Text("0");
        }
        return new Text(getToBinary(num.get(), index.get())+"");
    }
    /**
     * 获取num第index位的bit值
     * @param num
     * @param index
     * @return
     */
    public Text evaluate(IntWritable num, IntWritable index) {
        if (!checkData(num, index)) {
            return new Text("0");
        }
        return new Text(getToBinary(num.get(), index.get())+"");
    }

    /**
     * 数据是否合理
     * @param num
     * @param index
     * @return
     */
    private boolean checkData(Writable num, IntWritable index) {
        return (null != num && null != index && index.get() >= 0);
    }

    /**
     * 解析num第index位的值
     *
     * @param num   待解码值
     * @param index 取值位
     * @return 解码后的数值（0或1）
     */
    private long getToBinary(long num, int index) {
        return (num & (0x1 << index)) >> index;
    }

}
